﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Xml.Linq;
using System.Net;
using System.IO;

namespace SSM.DeepZoomViewer.Information
{
    /// <summary>
    /// 딥줌 정보를 관장하는 클래스
    /// </summary>
    public class DeepZoomInformationManager
    {
        /// <summary>
        /// DeepZoom 정보의 처리를 완료했을때 발생하는 이벤트
        /// </summary>
        public event EventHandler<CompletedEventArgs> Completed;

        /// <summary>
        /// 딥줌 정보를 다운로드 합니다.
        /// </summary>
        /// <param name="deepZoomInformationUrl"></param>
        public void DownloadDeepZoomInformation(Uri deepZoomInformationUrl)
        {
            // 딥줌 정보 다운로드 시작
            HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(deepZoomInformationUrl);

            httpWebRequest.BeginGetResponse(new AsyncCallback(DeepZoomInformationDownloadCallback), httpWebRequest);
        }

        /// <summary>
        /// DeepZoom 정보가 기록된 xml을 파싱하는 메서드
        /// </summary>
        /// <param name="informationUrl">DeepZoom 정보가 있는 URL</param>
        private DeepZoomInformation Parse(string informationXml)
        {
            DeepZoomInformation deepZoomImageInformation = new DeepZoomInformation();

            // XML Parsing
            XDocument xDocument = XDocument.Parse(informationXml);

            deepZoomImageInformation.TileSize = Convert.ToInt32(xDocument.Root.Attribute("TileSize").Value);
            deepZoomImageInformation.Format = xDocument.Root.Attribute("Format").Value;

            XElement xElement = xDocument.Root.Descendants().Single();
            deepZoomImageInformation.Width = Convert.ToInt32(xElement.Attribute("Width").Value);
            deepZoomImageInformation.Height = Convert.ToInt32(xElement.Attribute("Height").Value);

            return deepZoomImageInformation;
        }

        /// <summary>
        /// 딥줌 정보 다운로드가 완료된 경우 호출되는 메서드
        /// </summary>
        /// <param name="asynchronousResult"></param>
        private void DeepZoomInformationDownloadCallback(IAsyncResult asynchronousResult)
        {
            HttpWebRequest httpWebRequest = null;
            HttpWebResponse httpWebResponse = null;
            StreamReader streamReader = null;

            try
            {
                httpWebRequest = (HttpWebRequest)asynchronousResult.AsyncState;

                httpWebResponse = (HttpWebResponse)httpWebRequest.EndGetResponse(asynchronousResult);

                streamReader = new StreamReader(httpWebResponse.GetResponseStream());

                char[] xmlChar = new char[httpWebResponse.ContentLength];

                int count = streamReader.Read(xmlChar, 0, (int)httpWebResponse.ContentLength);

                string informationXml = new string(xmlChar, 0, count);

                DeepZoomInformation deepZoomInformation = Parse(informationXml);

                if (Completed != null)
                    Completed(this, new CompletedEventArgs() { DeepZoomInformation = deepZoomInformation });
            }
            finally
            {
                if (streamReader != null)
                    streamReader.Close();

                if (httpWebResponse != null)
                    httpWebResponse.Close();
            }
        }
    }
}
